home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
mxcode
/
adnmod02
/
gus.inc
< prev
next >
Wrap
Text File
|
1995-03-14
|
9KB
|
420 lines
const
_active_voice = $102;
_command = $103;
_data_low = $104;
_data_high = $105;
_dram_io = $107;
active_voice : word = _active_voice;
command : word = _command;
data_low : word = _data_low;
data_high : word = _data_high;
dram_io : word = _dram_io;
gus_info : array[0..7] of byte = ($42,$45,$54,$41,$2f,$41,$44,$4e);
{$s-}
Procedure GUSDelay; Assembler;
ASM
mov dx,base
add dx,$100
in al, dx
in al, dx
in al, dx
in al, dx
in al, dx
in al, dx
in al, dx
End;
Function VoicePos( V : Byte) : Longint;
Var
P : Longint;
I, Temp0, Temp1 : Word;
Begin
Port [active_voice] := V;
Port [command] := $8A;
Temp0 := Portw[data_low];
Port [command] := $8B;
Temp1 := Portw[data_low];
VoicePos := (Temp0 SHL 7)+ (Temp1 SHR 8);
End;
Function GUSPeek(Loc : Longint) : Byte;
Var
B : Byte;
AddLo : Word;
AddHi : Byte;
Begin
AddLo := Loc AND $FFFF;
AddHi := LongInt(Loc AND $FF0000) SHR 16;
Port [base+$103] := $43;
Portw[base+$104] := AddLo;
Port [base+$103] := $44;
Port [base+$105] := AddHi;
B := Port[base+$107];
GUSPeek := B;
End;
Procedure GUSPoke(Loc : Longint; B : Byte);
Var
AddLo : Word;
AddHi : Byte;
Begin
AddLo := Loc AND $FFFF;
AddHi := longint(Loc and $ff0000) shr 16;
Port [Base+$103] := $43;
Portw[Base+$104] := AddLo;
Port [Base+$103] := $44;
Port [Base+$105] := AddHi;
Port [Base+$107] := B;
End;
Function GUSProbe(adr : word) : Boolean;
Var
B: Byte;
obase : word;
Begin
obase := base;
base := adr;
Port [base+$103] := $4C;
Port [base+$105] := 0;
GUSDelay;
GUSDelay;
Port [base+$103] := $4C;
Port [base+$105] := 1;
GUSPoke(0, $AA);
GUSPoke($100, $55);
B := GUSPeek(0);
base := obase;
If B = $AA then GUSProbe := True else GUSProbe := False;
End;
Procedure GUSFind;
Var
I : Word;
b : word;
Begin
if base = $200 then begin
i := 1;
while i < 8 do begin
B := $200 + I*$10;
If GUSProbe(b) then I := 8;
inc(i);
End;
if b < $280 then base := b
else base := $200;
end;
if base <> $200 then begin
active_voice := base+_active_voice;
command := base+_command;
data_low := base+_data_low;
data_high := base+_data_high;
dram_io := base+_dram_io;
end;
End;
Function GUSFindMem : Longint;
{ Returns how much RAM is available on the GUS }
Var
I : Longint;
B : Byte;
Begin
GUSPoke($40000, $AA);
If GUSPeek($40000) <> $AA then I := $3FFFF
else
Begin
GUSPoke($80000, $AA);
If GUSPeek($80000) <> $AA then I := $8FFFF
else
Begin
GUSPoke($C0000, $AA);
If GUSPeek($C0000) <> $AA then I := $CFFFF
else I := $FFFFF;
End;
End;
guspoke(0,$aa);
if guspeek(0) <> $aa then i := 0;
GUSFindMem := I;
End;
Procedure GUSSetFreq( V : Byte; hz : Word); assembler;
asm
cli
mov dx,active_voice
mov al,v
out dx,al
mov dx,command
mov al,1
out dx,al
mov dx,data_low
mov ax,hz
out dx,ax
{Port [Base+$102] := V;
Port [Base+$103] := 1;
Portw[Base+$104] := hz;}
sti
end;
Procedure GUSVoiceControl( V, B : Byte);
Begin
asm cli end;
Port [Base+$102] := V;
Port [Base+$102] := V;
Port [Base+$102] := V;
Port [Base+$103] := $0;
Port [Base+$105] := B;
asm sti end;
End;
Procedure GUSSetBalance( V, Bal : Byte);
Begin
asm cli
mov dx,active_voice
mov al,v
out dx,al
mov dx,command
mov al,0ch
out dx,al
mov dx,data_high
mov al,bal
out dx,al
{Port [active_voice] := V;
Port [command] := $C;
Port [data_high] := Bal;}
sti
end;
End;
Procedure GUSSetVolume( V : Byte; Vol : Word); assembler;
asm
cli
mov dx,active_voice
mov al,v
out dx,al
mov dx,command
mov al,9
out dx,al
mov dx,data_low
mov ax,vol
out dx,ax
{Port [Base+$102] := V;
Port [Base+$103] := 9;
Portw[Base+$104] := Vol;} { 0-0ffffh, log ... not linear }
sti
End;
Procedure GUSSetLoopMode( V : Byte);
Var
Temp : Byte;
Begin
asm cli end;
Port [Base+$102] := V;
Port [Base+$102] := V;
Port [Base+$102] := V;
Port [Base+$103] := $80;
Temp := Port[Base+$105];
Port [Base+$103] := 0;
Port [Base+$105] := (Temp AND $E7) OR 0;
asm sti end;
End;
Procedure GUSStopVoice( V : Byte);
Var
Temp : Byte;
Begin
asm cli end;
Port [active_voice] := V;
Port [active_voice] := V;
Port [command] := $80;
Temp := Port[data_high];
Port [command] := 0;
Port [data_high] := (Temp AND $df) OR 3;
GUSDelay;
Port [command] := 0;
Port [data_high] := (Temp AND $df) OR 3;
asm sti end;
gussetvolume(v,0);
End;
Procedure GUSPlayVoice( V, Mode : Byte;VBegin, VStart, VEnd : Longint);
Begin
asm cli end;
Port [active_voice] := V;
Port [active_voice] := V;
port [command] := 0;
port [data_high] := 2; {stop voice}
Port [command] := $0A;
Portw[data_low] := (VBegin SHR 7) AND 8191;
Port [command] := $0B;
Portw[data_low] := (VBegin AND 127) SHL 9;
Port [command] := $02;
Portw[data_low] := (VStart SHR 7) AND 8191;
Port [command] := $03;
Portw[data_low] := (VStart AND 127) SHL 9;
Port [command] := $04;
Portw[data_low] := ((VEnd) SHR 7) AND 8191;
Port [command] := $05;
Portw[data_low] := ((VEnd) AND 127) SHL 9;
Port [command] := $0;
Port [data_high] := Mode and $fe;
asm sti end;
end;
Procedure GUSPlayAll( V, Mode : Byte;VBegin, VStart, VEnd : Longint;
freq,vol : word);
Begin
asm cli end;
asm
mov dx,active_voice {Port [active_voice] := V;}
mov al,v
out dx,al
mov cx,command {port [command] := 0;}
mov dx,cx
mov al,0
out dx,al
mov dx,data_high {port [data_high] := 2;} {stop voice}
mov al,2
out dx,al
mov dx,cx
mov al,9
out dx,al {port [command] := 9;}
mov dx,data_low
mov ax,vol
out dx,ax {portw[data_low] := vol;} {set volume}
mov dx,cx
mov al,1
out dx,al {port [command] := 1;}
mov dx,data_low
mov ax,freq
out dx,ax {portw[data_low] := freq;}
end;
Port [command] := $0A;
Portw[data_low] := (VBegin SHR 7) AND 8191;
Port [command] := $0B;
Portw[data_low] := (VBegin AND 127) SHL 9;
Port [command] := $02;
Portw[data_low] := (VStart SHR 7) AND 8191;
Port [command] := $03;
Portw[data_low] := (VStart AND 127) SHL 9;
Port [command] := $04;
Portw[data_low] := ((VEnd) SHR 7) AND 8191;
Port [command] := $05;
Portw[data_low] := ((VEnd) AND 127) SHL 9;
Port [command] := $0;
Port [data_high] := Mode and $fe;
asm sti end;
end;
procedure gusrelvoice(v : byte);
var
b : byte;
begin
port[active_voice] := v;
port[command] := $80;
b := port[data_high];
port[command] := 0;
port[data_high] := b and $fc;
end;
procedure gusrelvoices(n : byte); assembler;
asm
mov bl,n
@@1:
mov dx,base
add dx,102h
mov al,bl
out dx,al
inc dx
mov al,80h
out dx,al
add dx,2
in al,dx
mov al,0
sub dx,2
out dx,al
add dx,2
mov cl,al
and cl,0fdh
mov al,cl
out dx,al
dec bl
jnz @@1
end;
procedure GusSetOfs(v : byte;vbegin : longint);
begin
asm cli end;
Port [active_voice] := V;
Port [active_voice] := V;
Port [command] := $0A;
Portw[data_low] := (VBegin SHR 7) AND 8191;
Port [command] := $0B;
Portw[data_low] := (VBegin AND 127) SHL 9;
asm sti end;
end;
Procedure GUSReset;
var
n : integer;
Begin
Port[Base] := 3;
port [base+$103] := $4C;
port [Base+$105] := 1;
GUSDelay;
port [base+$103] := $4c;
port [base+$105] := 0;
gusdelay;
port [base+$103] := $4c;
port[base+$105] := 1;
gusdelay;
port [base+$103] := $4C;
port [Base+$105] := 7;
port [base+$103] := $0E;
port [Base+$105] := (13 OR $0C0);
gusdelay;
port[base] := 1;
Port[base+_command] := $4C;
Port[Base+_data_high] := 7;
n := gus_info[1];
for n := 1 to 14 do begin
port[base+_active_voice] := n;
port[base+_command] := 0;
port[base+_data_high] := 2; {stop all voices}
port[base+_command] := $d;
port[base+_data_high] := 2;
port[base+_command] := $a;
portw[base+_data_low] := 0;
port[base+_command] := $b;
portw[base+_data_low] := 0;
port[base+_command] := 9;
portw[base+_data_low] := 0;
end;
End;
{$s-}
procedure gusdeinit;
var
n : word;
begin
for n := 1 to 14 do gusstopvoice(n);
end;